<script setup lang="ts">
  import { queryInstInfrastructure } from '@/api/organization/nursing-home';
  import { useModeModalBinder } from '@/hooks/arco/useModeModalBinder';
  import { useSelectOption } from '@/hooks/arco/useSelectOption';
  import { useForm } from '@/hooks/arco/useForm';
  import { editAdmitInfo } from '@/api/file-management/file';
  import { createReusableTemplate } from '@vueuse/core';
  import { ref, unref } from 'vue';

  const props = withDefaults(
    defineProps<{
      showInModal?: boolean;
    }>(),
    {
      showInModal: true,
    }
  );

  const [DefineTemplate, ReuseTemplate] = createReusableTemplate();

  const elderSelected = ref({
    branchId: '',
    buildingId: '',
    floorNumber: '',
    roomId: '',
    bedId: '',
  });

  const isDisabled = (field: string, item: any) => {
    // @ts-ignore
    if (unref(elderSelected)[field] === item.value) {
      return false;
    }

    if (item.availableCount === 0) {
      return true;
    }

    return item.disabled === 1;
  };

  const form = useForm({
    state: {
      elderId: '',
      branchId: '',
      buildingId: '',
      floorNumber: '',
      roomId: '',
      bedId: '',
    },
    rules: {
      branchId: [
        {
          required: true,
          message: '请选择所在院区',
        },
      ],
      buildingId: [
        {
          required: true,
          message: '请选择所在建筑',
        },
      ],
      floorNumber: [
        {
          required: true,
          message: '请选择所在楼层',
        },
      ],
      roomId: [
        {
          required: true,
          message: '请选择所在房间',
        },
      ],
      bedId: [
        {
          required: true,
          message: '请选择所在床位',
        },
      ],
    },
  });

  const branchSelect = useSelectOption({
    leader: true,
    immediate: !props.showInModal,
    name: '所在院区',
    apiFun: queryInstInfrastructure,
    transformDataFun(data) {
      return data.branches;
    },
    fieldNames: {
      label: 'branchName',
      value: 'branchId',
      extra: 'buildings',
    },
    getValue() {
      return form.state.branchId;
    },
    enhanceExtraData: true,
  });

  const buildingSelect = useSelectOption({
    immediate: false,
    name: '所在建筑',
    getValue() {
      return form.state.buildingId;
    },
    apiFun: (id, extra) => {
      return Promise.resolve(extra || []);
    },
    enhanceExtraData: true,
    fieldNames: {
      label: 'buildingName',
      value: 'buildingId',
      extra: 'floors',
    },
    onChange(e) {
      // floorOptions.value = extra;
      // floorSelect.retry();
      form.state.buildingId = e;
    },
    upstream: branchSelect,
  });

  const floorSelect = useSelectOption({
    upstream: buildingSelect,
    immediate: false,
    name: '所在楼层',
    apiFun: (e, extra) => {
      return Promise.resolve(extra || []);
    },
    enhanceExtraData: true,
    fieldNames: {
      label: 'floorName',
      value: 'floorId',
      extra: 'rooms',
    },
    onChange(e) {
      form.state.floorNumber = e;
    },
    getValue() {
      return form.state.floorNumber;
    },
  });

  const roomSelect = useSelectOption({
    immediate: false,
    name: '所在房间',
    upstream: floorSelect,
    getValue() {
      return form.state.roomId;
    },
    apiFun: (e, extra) => {
      if (extra) {
        extra.sort((a: any, b: any) => {
          return a.roomNo - b.roomNo;
        });
      }
      return Promise.resolve(extra || []);
    },
    enhanceExtraData: true,
    fieldNames: {
      label: 'roomNo',
      value: 'roomId',
      extra: 'beds',
      disabled: 'userStatus',
      availableCount: 'availableCount',
      availableMessage: 'availableMessage',
    },
    onChange(e) {
      form.state.roomId = e;
    },
  });

  const bedSelect = useSelectOption({
    immediate: false,
    name: '所在床位',
    upstream: roomSelect,
    apiFun: (e, extra: any) => {
      if (extra) {
        extra.sort((a: any, b: any) => {
          return a.bedNo - b.bedNo;
        });
      }
      return Promise.resolve(extra || []);
    },
    getValue() {
      return form.state.bedId;
    },
    enhanceExtraData: true,
    fieldNames: {
      label: 'bedNo',
      value: 'bedId',
      disabled: 'userStatus',
    },
    onChange(e) {
      form.state.bedId = e;
    },
  });

  const editModal = useModeModalBinder({
    modes: ['edit'] as const,
    renderTitle() {
      return '编辑床位';
    },
    onShow(mode, otherParams) {
      form.setFieldsValue({
        elderId: otherParams.elderId,
        branchId: otherParams.branchId,
        buildingId: otherParams.buildingId,
        floorNumber: otherParams.floorNumber,
        roomId: otherParams.roomId,
        bedId: otherParams.bedId,
      });

      elderSelected.value = otherParams;

      branchSelect.retry();
    },
    async onOkClick() {
      await form.validate();
      return editAdmitInfo(form.state);
    },
  });

  defineExpose({
    ...editModal.expose,
    validate: form.validate,
    getData: () => {
      return form.state;
    },
    setData: (data: any) => {
      form.setFieldsValue(data);
    },
  });
</script>

<template>
  <DefineTemplate>
    <a-form
      class="bed-form"
      :layout="showInModal ? 'vertical' : 'horizontal'"
      v-bind="form.bindProps"
    >
      <a-form-item field="branchId" label="所在院区">
        <a-select
          v-model="form.state.branchId"
          v-bind="branchSelect.bindProps"
          :style="{ width: '100%' }"
        />
      </a-form-item>
      <a-form-item field="buildingId" label="所在建筑">
        <a-select
          v-model="form.state.buildingId"
          v-bind="buildingSelect.bindProps"
          :options="undefined"
          :style="{ width: '100%' }"
        >
          <a-option
            v-for="(item, index) of buildingSelect.bindProps.options"
            :key="index"
            :value="item.value"
            :label="item.label"
            :disabled="item.disabled"
            :class="{
              'option-used': item.disabled,
              'options-checked': item.value === form.state.buildingId,
            }"
          />
        </a-select>
      </a-form-item>

      <a-form-item field="floorNumber" label="所在楼层">
        <a-select
          v-model="form.state.floorNumber"
          v-bind="floorSelect.bindProps"
          :style="{ width: '100%' }"
        />
      </a-form-item>

      <a-form-item field="roomId" label="所在房间">
        <a-select
          v-model="form.state.roomId"
          v-bind="roomSelect.bindProps"
          :options="undefined"
          :style="{ width: '100%' }"
        >
          <a-option
            v-for="(item, index) of roomSelect.bindProps.options"
            :key="index"
            :value="item.value"
            :disabled="isDisabled('roomId', item)"
            :label="item.label"
            :class="{
              'options-checked': item.value === form.state.roomId,
              'option-disabled option-normal': true,
            }"
            :data-info="item.availableMessage"
          >
          </a-option>
        </a-select>
      </a-form-item>

      <a-form-item field="bedId" label="所在床位">
        <a-select
          v-model="form.state.bedId"
          v-bind="bedSelect.bindProps"
          :style="{ width: '100%' }"
          :options="undefined"
        >
          <a-option
            v-for="(item, index) of bedSelect.bindProps.options"
            :key="index"
            :value="item.value"
            :label="item.label"
            :disabled="isDisabled('bedId', item)"
            data-info="已占用"
            :class="{
              'option-disabled': true,
              'options-checked': item.value === form.state.bedId,
            }"
          />
        </a-select>
      </a-form-item>
    </a-form>
  </DefineTemplate>
  <a-drawer
    v-if="showInModal"
    position="right"
    width="400px"
    v-bind="editModal.bindProps"
  >
    <ReuseTemplate />
  </a-drawer>
  <div v-else>
    <ReuseTemplate />
  </div>
</template>

<style lang="less">
  .option-normal::after {
    content: attr(data-info);
    margin-left: auto;
  }

  .arco-select-option-disabled.option-disabled::after {
    content: attr(data-info);
    margin-left: auto;
  }

  .options-checked::after {
    content: '√';
    margin-left: auto;
  }

  .option-disabled.arco-select-option-disabled {
    color: rgb(var(--primary-2)) !important;
  }

  .options-checked {
    color: rgb(var(--primary-6)) !important;
  }
</style>
